package xyz.myachin.downloader.dm

import android.app.DownloadManager
import android.app.Service
import android.content.Context
import android.database.Cursor
import android.net.Uri
import xyz.myachin.downloader.settings.Settings
import xyz.myachin.downloader.ui.share.SharingType

object Downloader {
    private lateinit var downloadManager: DownloadManager

    fun setup(context: Context) {
        downloadManager = context.getSystemService(Service.DOWNLOAD_SERVICE) as DownloadManager
    }

    fun prepareDownloadTask(uri: Uri): DownloadManager.Request {
        return DownloadManager.Request(uri)
            .setAllowedOverMetered(Settings.isAllowedDownloadOverMetered())
            .setAllowedOverRoaming(Settings.isAllowDownloadOverRoaming())
            .setNotificationVisibility(Settings.howShowDownloadNotification())
    }

    fun enqueue(
        dmReq: DownloadManager.Request,
        sharingType: SharingType
    ): Long {
        val taskId = downloadManager.enqueue(dmReq)
        Settings.writeDownloadTaskIdWithType(taskId, sharingType)
        return taskId
    }

    fun removeTasks(vararg taskIds: Long): Int {
        Settings.removeDownloadTaskId(*taskIds)
        return downloadManager.remove(*taskIds)
    }

    fun getLocalUriForDownloadedFile(taskId: Long): Uri {
        downloadManager.getUriForDownloadedFile(taskId)?.run {
            return this
        }
        return Uri.parse("")
    }

    fun getRemoteUriForDownloadedFile(taskId: Long): String {
        downloadManager.query(DownloadManager.Query().setFilterById(taskId)).let { cur ->
            if (cur.moveToFirst()) {
                return cur.getString(cur.getColumnIndex(DownloadManager.COLUMN_URI))
            }
        }
        return ""
    }

    fun getMimeTypeForDownloadedFile(taskId: Long): String {
        downloadManager.getMimeTypeForDownloadedFile(taskId)?.run {
            return this
        }
        return ""
    }

    fun getFinishedDownloads(): Cursor? {
        return downloadManager.query(
            DownloadManager.Query()
                .setFilterByStatus(DownloadManager.STATUS_FAILED or DownloadManager.STATUS_SUCCESSFUL)
        )
    }

    fun removeAllFinishedDownloads(): Boolean {
        getFinishedDownloads()?.let { cursor ->
            val size = cursor.count
            if (size == 0) return true
            val tasks = LongArray(size)
            var i = 0
            while (cursor.moveToNext()) {
                tasks[i] = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_ID))
                i++
            }
            if (removeTasks(*tasks) == size) return true
        }
        return false
    }
}